package xin.marcher.module.seller.test.mapper;

import junit.framework.TestCase;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import org.apache.commons.lang3.RandomUtils;
import org.apache.commons.lang3.time.DateUtils;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import xin.marcher.module.common.domain.BaseDO;
import xin.marcher.module.seller.SellerApplication;
import xin.marcher.module.seller.domain.entity.SellerGroupDO;
import xin.marcher.module.seller.domain.entity.SellerGroupRelationDO;
import xin.marcher.module.seller.domain.entity.SellerInfoDO;
import xin.marcher.module.seller.mapper.SellerGroupMapper;
import xin.marcher.module.seller.mapper.SellerGroupRelationMapper;
import xin.marcher.module.seller.mapper.SellerInfoMapper;

import java.text.ParseException;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.Executors;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicInteger;

/**
 *
 */
@SpringBootTest(classes = SellerApplication.class)
@RunWith(SpringJUnit4ClassRunner.class)
public class ForJmeterCreateMockData extends TestCase {

    public static final Range SELLER_INFO_ID_RANGE = new Range(20_000_001, 20_001_000);

    public static final Range SELLER_GROUP_ID_RANGE = new Range(300_001, 301_000);

    public static final AtomicInteger ATOMIC_INTEGER = new AtomicInteger();

    @Autowired
    private SellerInfoMapper sellerInfoMapper;

    @Autowired
    private SellerGroupMapper sellerGroupMapper;

    @Autowired
    private SellerGroupRelationMapper sellerGroupRelationMapper;

    /**
     * seller_info 表
     */
    @Test
    public void sellerInfo() {
        List<Runnable> tasks = new ArrayList<>();
        for (Long sellerId : SELLER_INFO_ID_RANGE.asList()) {
            SellerInfoDO entity = new SellerInfoDO();
            entity.setSellerId(sellerId);
            entity.setSellerCode(appendGrowingNum("WJ-"));
            entity.setSellerName(appendGrowingNum("SellerName"));
            entity.setSellerDesc(appendGrowingNum("SellerDesc"));
            entity.setSellerType(computeSellerTypeById(sellerId));
            entity.setSellerPosition(100);
            entity.setSellerStatus(1);
            entity.setLastNode(1);
            setCommonFieldValue(entity);
            tasks.add(() -> sellerInfoMapper.insert(entity));
        }
        executeTaskWithThreadPool(tasks);
    }

    /**
     * seller_group 表
     */
    @Test
    public void sellerGroup() {
        List<Runnable> tasks = new ArrayList<>();
        for (Long sellerGroupId : SELLER_GROUP_ID_RANGE.asList()) {
            SellerGroupDO entity = new SellerGroupDO();
            entity.setSellerGroupId(sellerGroupId);
            entity.setSellerGroupName(appendGrowingNum("SellerGroupName"));
            entity.setSellerGroupType(1/*自营*/);
            entity.setSellerGroupStatus(1/*有效*/);
            setCommonFieldValue(entity);
            tasks.add(() -> sellerGroupMapper.insert(entity));
        }
        executeTaskWithThreadPool(tasks);
    }

    /**
     * seller_group_relation 表
     */
    @Test
    public void sellerGroupRelation() {
        List<Runnable> tasks = new ArrayList<>();
        for (Long sellerGroupId : SELLER_GROUP_ID_RANGE.asList()) {
            SellerGroupRelationDO entity = new SellerGroupRelationDO();
            entity.setSellerGroupId(sellerGroupId);
            entity.setSellerId(sellerGroupId + 19_700_000);
            setCommonFieldValue(entity);
            tasks.add(() -> sellerGroupRelationMapper.insert(entity));
        }
        executeTaskWithThreadPool(tasks);
    }


    private void executeTaskWithThreadPool(List<Runnable> tasks) {
        ThreadPoolExecutor threadPoolExecutor = (ThreadPoolExecutor) Executors.newFixedThreadPool(100);
        for (Runnable task : tasks) {
            threadPoolExecutor.execute(task);
        }
        // 循环等待线程池里的任务都执行完
        while (threadPoolExecutor.getQueue().size() != 0) {
            try {
                TimeUnit.SECONDS.sleep(1);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
        // 现在可以关闭线程池了
        threadPoolExecutor.shutdown();
    }


    private void setCommonFieldValue(BaseDO entity) {
        try {
            entity.setDelFlag(getYesInteger());
            entity.setCreateUser(getFixedInteger());
            entity.setCreateTime(DateUtils.parseDate("2022-04-02 00:00:00", "yyyy-MM-dd HH:mm:ss"));
            entity.setUpdateUser(getFixedInteger());
            entity.setUpdateTime(DateUtils.parseDate("2022-04-02 00:00:00", "yyyy-MM-dd HH:mm:ss"));
        } catch (ParseException ignore) {
        }
    }

    private Integer computeSellerTypeById(Long id) {
        return (int) (id % 2) + 1;
    }

    private Integer getYesInteger() {
        return 1;
    }

    private String appendGrowingNum(String str) {
        return str + ATOMIC_INTEGER.incrementAndGet();
    }

    private Integer getFixedInteger() {
        return 1;
    }

    @Data
    @NoArgsConstructor
    @AllArgsConstructor
    public static class Range {
        // 前闭
        private long start;
        // 后也闭
        private long end;

        public List<Long> asList() {
            List<Long> list = new ArrayList<>();
            for (long i = start; i <= end; i++) {
                list.add(i);
            }
            return list;
        }

        public Long randomOne() {
            return RandomUtils.nextLong(start, end + 1);
        }
    }
}
